#include "OSRMRouter.h"

#include <QDebug>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QDomNode>
#include <QDomNodeList>
#include <QStringList>

OSRMRouter::OSRMRouter(QString host, QString port)
    :host_(host), port_(port)
{
    networkRouteAccess_ = new QNetworkAccessManager(this);
    connect(networkRouteAccess_, SIGNAL(finished(QNetworkReply*)), this, SLOT(readXml(QNetworkReply*)));
}

OSRMRouter::~OSRMRouter()
{
}

void OSRMRouter::findRoute(QPointF start, QPointF dest)
{
    QString urlStr = "http://" + host_ + ":" + port_ + "/route";
    urlStr += "&" + QString::number(start.y(), 'f') + "&" + QString::number(start.x(), 'f');
    urlStr += "&" + QString::number(dest.y(), 'f') + "&" + QString::number(dest.x(), 'f');
    qDebug()<<urlStr;

    currentRoute_.clear();
    networkRouteAccess_->get(QNetworkRequest(QUrl(urlStr)));
}

QList<QPointF>& OSRMRouter::currentRouteRef()
{
    return currentRoute_;
}

void OSRMRouter::readXml(QNetworkReply *reply)
{
    if(reply->error() != QNetworkReply::NoError)
    {
        qDebug()<<"Error";
        emit routingFinished(FAILD_RETRIEVE);
        return;
    }
    qDebug()<<"Get something";

    QDomDocument document;
    if(document.setContent(reply))
    {
        qDebug()<<"Get xml";
        int result = parseXml(&document);
        emit routingFinished(result);
    }
    else
    {
        qDebug()<<"Get plain text";
        emit routingFinished(INVALID_DATA_FORMAT);
    }
}

int OSRMRouter::parseXml(QDomDocument *document)
{
    try
    {
        QDomElement element;
        QDomNodeList nodeList;

        nodeList = document->elementsByTagName("kml");
        if(nodeList.isEmpty())
            throw -1;
        element = nodeList.at(0).toElement();

        nodeList = document->elementsByTagName("Document");
        if(nodeList.isEmpty())
            throw -1;
        element = nodeList.at(0).toElement();

        nodeList = document->elementsByTagName("Placemark");
        if(nodeList.isEmpty())
            throw -1;
        element = nodeList.at(0).toElement();

        nodeList = document->elementsByTagName("GeometryCollection");
        if(nodeList.isEmpty())
            throw -1;
        element = nodeList.at(0).toElement();

        nodeList = document->elementsByTagName("LineString");
        if(nodeList.isEmpty())
            throw -1;
        element = nodeList.at(0).toElement();

        nodeList = document->elementsByTagName("coordinates");
        if(nodeList.isEmpty())
            throw -1;
        element = nodeList.at(0).toElement();

        if(!parseStringWithPoints(element.text()))
            throw -1;

        return NO_ERROR;
    }
    catch(int &e)
    {
        qDebug()<<"Something wrong with xml document";
        return INVALID_DATA_FORMAT;
    }
}

bool OSRMRouter::parseStringWithPoints(QString pointsStr)
{
    QStringList innerStrList;
    QStringList strList;
    strList = pointsStr.split(" ");

    QStringListIterator it(strList);
    while(it.hasNext())
    {
        innerStrList = it.next().split(',');
        if(innerStrList.size() != 2)
            continue;
        QPointF tmpPoint(innerStrList.at(0).toDouble(), innerStrList.at(1).toDouble());
        currentRoute_.push_back(tmpPoint);
    }

    return true;
}
